﻿//AcademicPlanner - course registration planning web app.
//Copyright (C) 2009  Boubacar Diallo

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Routing;
using System.Web.Mvc;
using AcademicPlanner.Domain;
using AcademicPlanner.Domain.Models;
using AcademicPlanner.Framework.Helpers;
using AcademicPlanner.Framework.Libraries.Mvc;
using AcademicPlanner.Framework.Libraries.Validation;
using AcademicPlanner.Presentation.Views.Site;

namespace AcademicPlanner.Presentation.Controllers
{
	/// <summary>
	/// SiteController is the MVC controller class for requests that are general
	/// to the AcademicPlanner application site.
	/// </summary>
	/// <since>1.0</since>
	[HandleError]
	public class SiteController : Controller
	{
		/// <summary>
		/// Handles requests by default (effectively the home page).
		/// This MVC action method returns the "Home" view in a "InNoSection" master page.
		/// </summary>
		/// <returns>The view representation of the home page.</returns>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Get)]
		public ActionResult Default()
		{
			if (SessionHelper.IsUserAuthenticated())
				return RedirectToAction("Overview", "MyPlan");

			return View("Home", "InNoSection");
		}

		/// <summary>
		/// Displays a web page of the Terms and Conditions of the application web site.
		/// </summary>
		/// <returns>A "Simple" view in a "InNoSection" master page.</returns>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Get)]
		public ViewResult Terms()
		{
			var vViewModel = new SimpleViewModel();

			vViewModel.Heading = Tr("Terms & Conditions");
			vViewModel.Content = App_LocalResources.StaticPages.TermsAndConditions;

			return View("Simple", "InNoSection", vViewModel);
		}

		/// <summary>
		/// Displays a web page of the information about the application web site.
		/// </summary>
		/// <returns>A "Simple" view in a "InNoSection" master page.</returns>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Get)]
		public ViewResult About()
		{
			var vViewModel = new SimpleViewModel();

			vViewModel.Heading = Tr("About Us");
			vViewModel.Content = App_LocalResources.StaticPages.AboutUs;

			return View("Simple", "InNoSection", vViewModel);
		}

		/// <summary>
		/// Displays a web page of the Privacy Notice of the application web site.
		/// </summary>
		/// <returns>A "Simple" view in a "InNoSection" master page.</returns>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Get)]
		public ViewResult Privacy()
		{
			var vViewModel = new SimpleViewModel();

			vViewModel.Heading = Tr("Privacy Notice");
			vViewModel.Content = App_LocalResources.StaticPages.PrivacyNotice;

			return View("Simple", "InNoSection", vViewModel);
		}

		/// <summary>
		/// Processes a web request to sign the session user in.
		/// </summary>
		/// <remarks>
		/// This methods makes sure that neither the submitted
		/// username nor password are empty. It then requests
		/// from the domain layer whether the submitted data is
		/// authentic in which case it marks the session user
		/// as authenticated and resets all user related data
		/// in the session including username and password.
		/// </remarks>
		/// <returns>Instructions to the browser in json format about the result of the action.</returns>
		/// <seealso cref="T:AcademicPlanner.Presentation.JsonResultData"/>
		/// <seealso cref="P:Application"/>
		/// <seealso cref="P:AcademicPlanner.Presentation.AcademicPlannerWebApp.DomainMaster"/>
		/// <seealso cref="P:AcademicPlanner.Domain.DomainMaster.Auth"/>
		/// <seealso cref="M:AcademicPlanner.Domain.Components.AuthMngr.IsAuthenticUser"/>
		/// <seealso cref="M:AcademicPlanner.Framework.Helpers.SessionHelper.ResetUserName"/>
		/// <seealso cref="M:AcademicPlanner.Framework.Helpers.SessionHelper.ResetUserPassword"/>
		/// <seealso cref="M:AcademicPlanner.Framework.Helpers.SessionHelper.ResetIsUserAuthenticated"/>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Post)]
		[AjaxOnly]
		public JsonResult Signin()
		{
			JsonResultData vResult = new JsonResultData();

			Post.NamesPrefix = "";
			var vUsername = Post.GetAsString("Name", "User");
			var vUserPassword = Post.GetAsString("Password", "User");
			var vRememberMe = Post.GetAsBoolean("RememberMe", "User");

			if (!StringValidator.IsNotBlank(vUsername) || !StringValidator.IsNotBlank(vUserPassword))
			{
				vResult.errors = Form.SummarizeError(string.Format(Tr("You must enter {0} and {1}."),
																		Labels.Get("Name", "User"),
																		Labels.Get("Password", "User")));
			}
			else
			{
				if (!Application.DomainMaster.Auth.IsAuthenticUser(vUsername, vUserPassword))
				{
					vResult.errors = Form.SummarizeError(string.Format(Tr("{0}/{1} is wrong."),
																		Labels.Get("Name", "User"),
																		Labels.Get("Password", "User")));
				}
				else
				{
					var vRedirectData = (RouteValueDictionary)
											SessionHelper.Get("Presentation.LoginRedirection") ?? null;
					var vPlan = Application.DomainMaster
										.Planning.GetAcademicPlan(vUsername);

					if (vRedirectData == null)
					{
						vRedirectData = new RouteValueDictionary(new
						{
							controller = "MyPlan",
							action = "Overview"
						});
					}

					SessionHelper.ResetUserName(vUsername);
					SessionHelper.ResetUserPassword(vUserPassword);
					SessionHelper.ResetIsUserAuthenticated(true);
					// TODO: RESET USER RELATED SESSION DATA I.E KEYS "USER.*"
					SessionHelper.Reset("User.PlanId", vPlan.EntityId);

					if (vRememberMe)
					{
						var vDays = (string)ConfigHelper
										.GetPresentationSectionValue("loginSettings", "rememberMeDuration");
						var vDate = DateTime.Now.AddDays(Convert.ToInt32(vDays));
						vResult.evaluate = string.Format("Cookie.set('{0}', '{1}', {{expires: new Date('{2}'), path: '/'}});",
											(string)ConfigHelper.GetPresentationSectionValue("loginSettings", "usernameCookieName"),
											vUsername,
											vDate.ToLongDateString());
						vResult.evaluate += string.Format("\nCookie.set('{0}', '{1}', {{expires: new Date('{2}'), path: '/'}});",
											(string)ConfigHelper.GetPresentationSectionValue("loginSettings", "passwordCookieName"),
											vUserPassword,
											vDate.ToLongDateString());
					}
					else
					{
						vResult.evaluate = string.Format("Cookie.remove('{0}', {{path: '/'}});",
											(string)ConfigHelper.GetPresentationSectionValue("loginSettings", "usernameCookieName"));
						vResult.evaluate += string.Format("\nCookie.remove('{0}', {{path: '/'}});",
											(string)ConfigHelper.GetPresentationSectionValue("loginSettings", "passwordCookieName"));
					}

					vResult.redirect = Url.RouteUrl(vRedirectData);
				}
			}

			return Json(vResult);
		}

		/// <summary>
		/// Process a request to sign the session user out.
		/// This method simply resets all user related data
		/// in the session including username and password.
		/// </summary>
		/// <returns>Instructions to the browser in json format about the result of the action.</returns>
		/// <seealso cref="T:AcademicPlanner.Presentation.JsonResultData"/>
		/// <seealso cref="M:AcademicPlanner.Framework.Helpers.SessionHelper.ResetUserName"/>
		/// <seealso cref="M:AcademicPlanner.Framework.Helpers.SessionHelper.ResetUserPassword"/>
		/// <seealso cref="M:AcademicPlanner.Framework.Helpers.SessionHelper.ResetIsUserAuthenticated"/>
		/// <since>1.0</since>
		[AcceptVerbs(HttpVerbs.Post)]
		[AjaxOnly]
		public JsonResult Signout()
		{
			var vResult = new JsonResultData();

			SessionHelper.ResetUserName("");
			SessionHelper.ResetUserPassword("");
			SessionHelper.ResetIsUserAuthenticated(false);
			// TODO: RESET USER RELATED SESSION DATA I.E KEYS "USER.*"
			SessionHelper.Reset("User.PlanId", null);

			vResult.reload = true;

			return Json(vResult);
		}
	}
}
